package server;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.UnrecoverableKeyException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLServerSocket;

import protocol.Info;
import sslsockets.SSLSocketHandler;

public class VoteServer
{
    static String keyStoreFile;
    static String trustKeyStoreFile;
    static private char[] keyStorePassword;
    static private char[] trustKeyStorePassword;
    private KeyStore keyStore;
    private KeyStore trustKeyStore;
    static public RSAPrivateKey PKWPrivateKey;
    static public RSAPublicKey PKWPublicKey;
    private boolean isRunning = true;

    public VoteServer()
    {
        try
        {
            keyStore = KeyStore.getInstance( KeyStore.getDefaultType() );
            trustKeyStore = KeyStore.getInstance( KeyStore.getDefaultType() );
            FileInputStream fis = new FileInputStream( new File( keyStoreFile ) );
            keyStore.load( fis, keyStorePassword );
            PKWPrivateKey = (RSAPrivateKey)keyStore.getKey( "PKW", keyStorePassword );
            PKWPublicKey = (RSAPublicKey)keyStore.getCertificateChain( "PKW" )[ 0 ].getPublicKey();
            fis.close();
            fis = new FileInputStream( new File( trustKeyStoreFile ) );
            trustKeyStore.load( fis, trustKeyStorePassword );
        }
        catch( Exception e )
        {
            throw new RuntimeException( e );
        }
    }

    static
    {
        ServerResources resources = new ServerResources();
        keyStoreFile = (String)resources.getObject( "keyStoreFile" );
        trustKeyStoreFile = (String)resources.getObject( "trustKeyStoreFile" );
        keyStorePassword = (char[])resources.getObject( "keyStorePassword" );
        trustKeyStorePassword = (char[])resources.getObject( "trustKeyStorePassword" );
    }

    public void listenSocket()
    {
        try
        {
            ExecutorService pool = Executors.newCachedThreadPool();
            SSLServerSocket sslSocket = SSLSocketHandler.createServerSocket( Info.VOTE_PORT, trustKeyStore, keyStore, keyStorePassword );
            sslSocket.setNeedClientAuth( true );
            System.out.println( "VoteServer: listening on port: " + Info.VOTE_PORT );
            while( isRunning )
            {
                VoteWorker vw;
                try
                {
                    vw = new VoteWorker( sslSocket.accept() );
                    pool.submit( vw );
                }
                catch( SSLHandshakeException e )
                {
                    System.out.println( "nie znaleziono zaufanego certyfikatu" );
                    e.printStackTrace();
                }
                catch( IOException e )
                {
                    e.printStackTrace();
                }
            }
        }
        catch( KeyStoreException e )
        {
            e.printStackTrace();
            System.exit( 1 );
        }
        catch( UnrecoverableKeyException e )
        {
            e.printStackTrace();
            System.exit( 1 );
        }
        catch( IOException e )
        {
            e.printStackTrace();
            System.exit( 1 );
        }
    }
}